#include <retro.h>
#include "retro.creator.h"

using namespace Retro::Creator::Drawing;
using namespace SPLib::Geom;

VOID Creator::Drawing::snapBounds(
  Bounds &bounds,
  LONG gridX,
  LONG gridY
  )
{
  if (bounds.cx < 0) {
    bounds.cx -= gridX - bounds.x % gridX;
    bounds.x += gridX - bounds.x % gridX;
  } else {
    bounds.cx += bounds.x % gridX;
    bounds.x -= bounds.x % gridX;
  }

  if (bounds.cy < 0) {
    bounds.cy -= gridY - bounds.y % gridY;
    bounds.y += gridY - bounds.y % gridY;
  } else {
    bounds.cy += bounds.y % gridY;
    bounds.y -= bounds.y % gridY;
  }

  if (bounds.cx == 0) bounds.cx = gridX;
  if (bounds.cy == 0) bounds.cy = gridY;

  int rx = abs(bounds.cx % gridX);
  int ry = abs(bounds.cy % gridY);

  if (rx) {
    if (bounds.cx < 0)
      bounds.cx -= gridX - rx;
    else
      bounds.cx += gridX - rx;
  }

  if (ry) {
    if (bounds.cy < 0)
      bounds.cy -= gridY - ry;
    else
      bounds.cy += gridY - ry;
  }
}

VOID Creator::Drawing::scaleBounds(
  Geom::Bounds &bounds,
  Geom::Size limits
  )
{
  int xFactor = bounds.cx < 0 ? -1 : 1;
  int yFactor = bounds.cy < 0 ? -1 : 1;

  bounds.absolute();

  int maxWidth    = min(bounds.cx, limits.cx - bounds.x);
  int maxHeight   = min(bounds.cy, limits.cy - bounds.y);
  int maxSize     = min(maxWidth, maxHeight);
  int maxSide     = max(maxWidth, maxHeight);

  maxSide = min(maxSide, maxSize);

  bounds.cx = maxSide;
  bounds.cy = maxSide;

  if (xFactor < 0) {
    bounds.x += bounds.cx;
    bounds.cx = -bounds.cx;
  }

  if (yFactor < 0) {
    bounds.y += bounds.cy;
    bounds.cy = -bounds.cy;
  }
}

VOID Creator::Drawing::drawCheckerboard(
  INT iSize,
  Gdip::Rect iBounds,
  Gdip::Graphics& g
  )
{
  Gdip::SolidBrush wBrush(0xFFCCCCCC);
  Gdip::Region wRegion;
  Gdip::PixelOffsetMode wOffsetMode = g.GetPixelOffsetMode();
  Gdip::CompositingMode wCompMode = g.GetCompositingMode();

  g.GetClip(&wRegion);
  g.SetCompositingMode(Gdip::CompositingModeSourceCopy);
  g.SetPixelOffsetMode(Gdip::PixelOffsetModeHalf);
  g.SetClip(iBounds);

  Geom::Size wSize = {
    (INT)ceil((REAL)iBounds.Width / iSize),
    (INT)ceil((REAL)iBounds.Height / iSize)
  };

  for (INT x = 0; x < wSize.cx; ++x)
  for (INT y = 0; y < wSize.cy; ++y)
  {
    if ((x + y) % 2 == 0)
    {
      g.FillRectangle(
        &wBrush,
        iBounds.X + x * iSize,
        iBounds.Y + y * iSize,
        iSize,
        iSize);
    }
  }

  g.SetCompositingMode(wCompMode);
  g.SetPixelOffsetMode(wOffsetMode);
  g.SetClip(&wRegion);
}
